/**
* All Rights Reserved , Copyright (C) 2021 , 青岛鼎信通讯股份有限公司
*
* DutyRecordService
* 值班人员记录表
*
* 修改纪录
* 2021-06-03 版本：1.0 chengengwei 创建。
* @version 版本：1.0
* @author 作者：chengengwei
* 创建日期：2021-06-03
*/
package com.topscomm.duty.service.impl;

import com.topscomm.basic.BasicEntity;
import com.topscomm.basic.exception.ServiceException;
import com.topscomm.basic.util.SQLAdapter;
import com.topscomm.cbo.pojo.CboDeptEntity;
import com.topscomm.cbo.service.ICboDeptService;
import com.topscomm.duty.DutySystemConst;
import com.topscomm.duty.pojo.DutyRecordEntity;
import com.topscomm.pub.util.ConvertUtil;
import com.topscomm.pub.util.StringBufferProxy;
import com.topscomm.pub.util.StringUtil;
import com.topscomm.tap.common.DatacodeCache;
import com.topscomm.tap.common.SessionUserBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;

import com.topscomm.duty.service.IDutyRecordService;
import com.topscomm.duty.service.impl.auto.DutyRecordServiceAuto;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@Service(value = "dutyRecordService")
@Scope(value = "singleton")
public class DutyRecordService extends DutyRecordServiceAuto implements IDutyRecordService {

    @Resource(name = "datacodeCache")
    private DatacodeCache datacodeCache;

    @Autowired
    private ICboDeptService cboDeptService;

    /**
     * @description:值班列表查询
     * @author: chengengwei
     * @date: 2021-06-03
     * @modify:
     */
    @Override
    public void queryOnDutyList(Map<String, Object> paraMap, Map<String, Object> resultMap) {
        String targetDate = ConvertUtil.convertToString(paraMap.get("date"));
        Map<String, Object> queryParams = new HashMap<>();
        queryParams.put("targetData", targetDate);
        List<Map<String, Object>> onDutyList = this.queryMap(queryParams, "queryOnDutyList");
        Map<String, List<Map<String, Object>>> onDutyGroupByDeptMap = onDutyList.stream()
                .collect(Collectors.groupingBy(item ->
                        ConvertUtil.convertToString(item.get(DutyRecordEntity.FieldFirstleveldeptname)),
                        () -> new TreeMap<>(), Collectors.toList()));
        List<Map<String, Object>> dataList = new ArrayList<>();
        onDutyGroupByDeptMap.forEach((k, v) -> {
            Map<String, Object> firstDeptDataMap = new HashMap<>();
            firstDeptDataMap.put("dept", k);
            firstDeptDataMap.put("rows", v);
            dataList.add(firstDeptDataMap);
        });
        resultMap.put("data", dataList);
    }

    /**
     * @description:值班表提交
     * @author: chengengwei
     * @date: 2021-06-04
     * @modify:
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void submitOnDutyList(Map<String, Object> paraMap, SessionUserBean userBean) {
        Date targetDate = ConvertUtil.convertToDate(paraMap.get("date"));
        List<Map<String, Object>> onDutyList = (List<Map<String, Object>>) paraMap.get("rows");
        // 获取CHO为当前用户的一级部门
        List<Map<String, Object>> firstDeptList = this.queryFirstDeptByCHOCode(userBean);
        // 如果firstDeptList为空，则查询当前用户是否额外配置了权限
        if (firstDeptList.isEmpty()) {
            List<Map<String, Object>> extraDutyConfigList = this.queryExtraDutyList(userBean);
            if (extraDutyConfigList.isEmpty()) {
                throw new ServiceException("您没有提交权限");
            }
            // 将额外权限数据进行处理
            this.handleExtraDutyData(extraDutyConfigList, firstDeptList);
        }
        // 若选择了其他部门下的员工，则提醒CHO
        StringBuffer remindMessage = new StringBuffer();
        List<BasicEntity> batchList = new ArrayList<>();
        onDutyList.forEach(item -> {
            DutyRecordEntity recordEntity = new DutyRecordEntity();
            // 通过部门id查询部门信息，判断属于哪个一级部门下
            CboDeptEntity workDept = this.cboDeptService.queryById(ConvertUtil.convertToString(item.get("deptid")));
            firstDeptList.forEach(dept -> {
                String deptcode = ConvertUtil.convertToString(dept.get("code"));
                String deptname = ConvertUtil.convertToString(dept.get("name"));
                if (workDept.getCode().contains(deptcode)) {
                    recordEntity.setFirstleveldeptcode(deptcode);
                    recordEntity.setFirstleveldeptname(deptname);
                }
            });
            // 若firstleveldeptcode字段为空，则说明当前CHO无法选择该员工
            if (StringUtil.isEmpty(recordEntity.getFirstleveldeptcode())) {
                remindMessage.append(item.get("name") + "【" + item.get("code") + "】、");
            }
            recordEntity.setOndutyusercode(ConvertUtil.convertToString(item.get("code")));
            recordEntity.setOndutyusername(ConvertUtil.convertToString(item.get("name")));
            recordEntity.setOndutyuserid(ConvertUtil.convertToLong(item.get("id")));
            recordEntity.setOndutydeptcode(workDept.getCode());
            recordEntity.setOndutydeptname(workDept.getName());
            recordEntity.setOndutydate(targetDate);
            batchList.add(recordEntity);
        });
        // 若remindMessage不为空则抛异常，并将提示信息放入
        if (remindMessage.length() > 0) {
            throw new ServiceException(remindMessage.substring(0, remindMessage.length() - 1) +
                    "不属于您所在一级部门下，无法选择");
        }
        // 删除原有记录
        String codes = "'" + firstDeptList.stream().map(item -> ConvertUtil.convertToString(item.get("code")))
                .collect(Collectors.joining("','")) + "'";
        StringBufferProxy whereSql = new StringBufferProxy();
        whereSql.appendSingle(" {0} in ({1}) and {2} = {3} ", DutyRecordEntity.FieldFirstleveldeptcode, codes,
                DutyRecordEntity.FieldOndutydate, SQLAdapter.toDateLong(ConvertUtil.convertToString(paraMap.get("date"))));
        this.deleteByWhere(whereSql.toString());
        this.insertBatch(batchList);
    }

    /**
     * @description:查询额外配置的权限
     * @author: chengengwei
     * @date: 2021-06-15
     * @modify:
     */
    private List<Map<String, Object>> queryExtraDutyList(SessionUserBean userBean) {
        List<Map<String, Object>> chooseDutyList = datacodeCache.getCodeListMap(DutySystemConst.ChooseDuty,
                "", "sortcode");
        return chooseDutyList.stream().filter(map -> {
            return userBean.getUser().getCode().equals(ConvertUtil.convertToString(map.get("name")));
        }).collect(Collectors.toList());
    }

    /**
     * @description:处理额外权限数据
     * @author: chengengwei
     * @date: 2021-06-15
     * @modify:
     */
    private void handleExtraDutyData(List<Map<String, Object>> extraDutyConfigList,
                                     List<Map<String, Object>> firstDeptList) {
        if (!extraDutyConfigList.isEmpty()) {
            String deptcodes = ConvertUtil.convertToString(extraDutyConfigList.get(0).get("code"));
            String[] deptCodesArr = deptcodes.split(",");
            StringBufferProxy whereSql = new StringBufferProxy();
            whereSql.appendSingle(" code in ({0}) ", "'" +
                    String.join("','", deptCodesArr) + "'");
            firstDeptList.addAll(this.cboDeptService.queryMapByWhere(whereSql.toString()));
        }
    }

    /**
     * @description:根据CHO查询其所在一级部门
     * @author: chengengwei
     * @date: 2021-06-05
     * @modify:
     */
    private List<Map<String, Object>> queryFirstDeptByCHOCode(SessionUserBean userBean) {
        Map<String, Object> queryParams = new HashMap<>();
        queryParams.put("usercode", userBean.getUser().getCode());
        return this.queryMap(queryParams, "queryFirstDeptByCHOCode");
    }

    /**
     * @description:根据CHO查询值班记录
     * @author: chengengwei
     * @date: 2021-06-05
     * @modify:
     */
    @Override
    public void queryOnDutyListByCHO(Map<String, Object> paraMap, Map<String, Object> resultMap,
                                     SessionUserBean userBean) {
        List<Map<String, Object>> firstDeptList = this.queryFirstDeptByCHOCode(userBean);
        // 若firstDeptList为空则查询额外配置权限
        if (firstDeptList.isEmpty()) {
            List<Map<String, Object>> extraDutyConfigList = this.queryExtraDutyList(userBean);
            // 将额外权限数据进行处理
            this.handleExtraDutyData(extraDutyConfigList, firstDeptList);
        }
        List<Map<String, Object>> dataList = new ArrayList<>();
        StringBufferProxy whereSql = new StringBufferProxy();
        firstDeptList.forEach(dept -> {
            whereSql.appendSingle(" {0} = '{1}' and {2} = {3} ", DutyRecordEntity.FieldFirstleveldeptcode,
                    ConvertUtil.convertToString(dept.get("code")), DutyRecordEntity.FieldOndutydate,
                    SQLAdapter.toDateLong(ConvertUtil.convertToString(paraMap.get("date"))));
            Map<String, Object> queryParams = new HashMap<>();
            queryParams.put("whereSql", whereSql.toString());
            List<Map<String, Object>> dutyRecordEntities = this.queryMap(queryParams, "queryOnDutyListByCHO");
            whereSql.clear();
            // 添加值班人员
            dataList.addAll(dutyRecordEntities);
        });
        resultMap.put("data", dataList);
    }

    /**
     * @description:判断当前用户是否为CHO
     * @author: chengengwei
     * @date: 2021-06-15
     * @modify:
     */
    @Override
    public void judgeIsCHO(Map<String, Object> resultMap, SessionUserBean sessionUserBean) {
        StringBufferProxy whereSql = new StringBufferProxy();
        String usercode = sessionUserBean.getUser().getCode();
        whereSql.appendSingle(" {0} = '{1}' ", CboDeptEntity.FieldHrmanagercode, usercode);
        List<CboDeptEntity> cboDeptEntities = this.cboDeptService.queryByWhere(whereSql.toString());
        List<Map<String, Object>> chooseDutyList = datacodeCache.getCodeListMap(DutySystemConst.ChooseDuty,
                "", "sortcode");
        resultMap.put("isCHO", cboDeptEntities.size() > 0 || chooseDutyList.stream()
                .anyMatch(map -> usercode.equals(ConvertUtil.convertToString(map.get("name")))));
    }
}
